import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Calendar;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
 * 
 * @author PUSS1401
 * 
 */
@WebServlet("/TimeReporting")
public class servletTimeReporting extends servletBase {
	private static final long serialVersionUID = 1L;
	private final int START = 0;
	private final int NEWTR = 2;
	private final int UPDATETR = 3;
	private final int VIEWTR = 1;
	private int state = 0;
	private String error = "";
	private HtmlGenerator gen = new HtmlGenerator();
	private TimeReport updateThisTR;
	private int week = 0;
	private String user = "", project = "";

	/**
	 * Creates a html-string listing all timereports appertained to the user.
	 *  
	 * @param timeReports
	 * 			An array of timereports to be inserted to the html-string
	 * @param type
	 * 			Determines if the timereports are to be updated or only viewed
	 * @return A html-string of a list with radio buttons and the listed timereports 
	 */
	private String selectTimereportForm(String[] timeReports, String type) {
		String html = "<form name=" + formElement("radio");
		html += " method=" + formElement("get") + "> ";

		for (int i = 0; i < timeReports.length; i++) {
			html += " <input type=" + formElement("radio") + "name="
					+ formElement(type) + " value="
					+ formElement(timeReports[i]) + " > "
					+ timeReports[i].toUpperCase() + " <br>";
		}
		html += " <input type=" + formElement("submit");
		html += " value=" + formElement("Select timeReport") + '>';
		html += " </form>";
		return html;
	}
	/**
	 * Creates a html-string of buttons that determines the function (new, update, view, remove).
	 * @return The html-string for the buttons
	 */
	private String chooseTimeReportForm() {
		String html = "<form action=" + formElement("TimeReporting")
				+ "method=" + formElement("get") + '>';
		html += "<button name=" + formElement("newTimeReport") + "type="
				+ formElement("submit") + "value=" + formElement("new")
				+ "> New TimeReport</button>";
		html += "<button name=" + formElement("viewTimeReport") + "type="
				+ formElement("submit") + "value=" + formElement("view")
				+ "> View TimeReport</button>";
		html += "<button name=" + formElement("updateTimeReport") + "type="
				+ formElement("submit") + "value=" + formElement("update")
				+ "> Update TimeReport</button>";
		html += "</form>";
		return html;
	}
	/**
	 * A servlet that handles timereporting for a member of a project. Extends servletBase.
	 * 
	 * First it is checked that an user is logged in and has chosen a project, otherwise the user is redirected to the appropriate page.
	 * 
	 * The user is given the choices to create, view, update and remove timereports.
	 * The view and update functions list all active timereports in the system, where a user can chose what timereport to work with.
	 * The remove function can only be reached via the view function.
	 * 
	 * 
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		HttpSession session = request.getSession(true);
		if (session == null) {
			response.sendRedirect("lostSession.html");
			return;
		}

		response.setContentType("text/html");
		PrintWriter out = response.getWriter();

		if (request.getQueryString() != null
				&& request.getQueryString().contains("newTimeReport")) {
			System.out.println(request.getQueryString());
			System.out.println("state 1");
			error = "";
			state = NEWTR;
			updateThisTR = null;
		}

		else if (request.getQueryString() != null
				&& request.getQueryString().indexOf(("viewTimeReport")) >= 0) {
			System.out.println(request.getQueryString());
			state = VIEWTR;
			error = "";
			System.out.println("state 2");
			updateThisTR = null;
		} else if (request.getQueryString() != null
				&& request.getQueryString().indexOf(("updateTimeReport")) >= 0) {
			System.out.println(request.getQueryString());
			state = UPDATETR;
			error = "";
			System.out.println("state 3");
		}

		else if (request.getQueryString() == null) {
			state = START; // Standard state
			updateThisTR = null;
		}
		if (!(request.getQueryString() == null)
				&& request.getQueryString().contains("weekDelete")) {

			if (!db.signedTR(user, project, week)) {
				db.removeTR(user, project, week);
			} else {
				out.println("Error");
			}
			week = 0;
		}

		if (!loggedIn(request)) {
			response.sendRedirect("LogIn");
		} else {
			if ((session.getAttribute("project").equals("noproject"))) {
				response.sendRedirect("Projects");
			} else {

				out.println(gen.getTop(session.getAttribute("name").toString(),
						session.getAttribute("project").toString(), db.getRole(
								session.getAttribute("name").toString(),
								session.getAttribute("project").toString())));
				out.println(gen.getProjMenu());
				out.println(chooseTimeReportForm());

				if (state == VIEWTR) {
					user = session.getAttribute("name").toString();
					project = session.getAttribute("project").toString();

					String[] Timereports = db.listActiveTRsUser(user, project);
					String timeReport = selectTimereportForm(Timereports,
							"ShowTimeReport");
					out.println(timeReport);
					String get = request.getQueryString();
					if (get != null && get.contains("ShowTimeReport")) {
						for (int i = 0; i < Timereports.length; i++) {
							System.out.println(request.getQueryString());
							System.out
									.println(Timereports[i].replace(" ", "+"));
							if (request.getQueryString().equals(
									"ShowTimeReport="
											+ Timereports[i].replace(" ", "+"))) {
								System.out.println(Integer
										.parseInt(Timereports[i].split(" ")[2])
										+ " "
										+ db.getTR(
												user,
												project,
												Integer.parseInt(Timereports[i]
														.split(" ")[2]))
												.getWeek());
								out.println(gen.viewTimeReport(db.getTR(user,
										project, Integer
												.parseInt(Timereports[i]
														.split(" ")[2]))));
								String deleteButtonURL = "TimeReporting?weekDelete="
										+ Integer.parseInt(Timereports[i]
												.split(" ")[2]);
								String html = "<form action="
										+ formElement(deleteButtonURL)
										+ "method=" + formElement("get") + '>';
								html += "<button name="
										+ formElement(deleteButtonURL)
										+ " onclick="
										+ formElement("return confirm('Vill du ta bort denna tidsrapport?')")
										+ "type=" + formElement("submit")
										+ "value=" + formElement("sign")
										+ ">Remove</button>";
								html += "</form>";
								week = Integer.parseInt(Timereports[i]
										.split(" ")[2]);
								if (!(db.signedTR(user, project, week))) {
									out.print(html);
								}
							}
						}
					}
				}

				if (state == UPDATETR) {
					user = session.getAttribute("name").toString();
					project = session.getAttribute("project").toString();

					String[] Timereports = db.listActiveTRsUser(user, project);
					String timeReport = selectTimereportForm(Timereports,
							"UpdateTimeReport");
					out.println(timeReport);
					String get = request.getQueryString();
					if (get != null && get.contains("UpdateTimeReport")) {
						for (int i = 0; i < Timereports.length; i++) {
							System.out.println(request.getQueryString());
							System.out
									.println(Timereports[i].replace(" ", "+"));
							if (request.getQueryString().equals(
									"UpdateTimeReport="
											+ Timereports[i].replace(" ", "+"))) {
								System.out.println(Integer
										.parseInt(Timereports[i].split(" ")[2])
										+ " "
										+ db.getTR(
												user,
												project,
												Integer.parseInt(Timereports[i]
														.split(" ")[2]))
												.getWeek());
								updateThisTR = db
										.getTR(user, project, Integer
												.parseInt(Timereports[i]
														.split(" ")[2]));
								out.println(gen
										.updateTimeReportForm(updateThisTR));
							}
						}
					}

					if (request.getParameter("week") != null) {
						if (!updateThisTR.signed()) {
							try {
								int week = Integer.parseInt(request
										.getParameter("week"));
								if (week != 0) {
									Boolean active = updateThisTR.active();
									Boolean signed = false;
									int[] array = new int[9];
									int[][] matrix = new int[9][4];

									for (int k = 0; k < 9; k++) {
										array[k] = Integer.parseInt(request
												.getParameter(Integer
														.toString(k + 1)));
									}
									for (int i = 0; i < 9; i++) {
										for (int j = 0; j < 4; j++) {
											matrix[i][j] = Integer
													.parseInt(request.getParameter(Integer
															.toString(i)
															+ Integer
																	.toString(j)));
										}
									}
									TimeReport uTR = new TimeReport(
											(String) session
													.getAttribute("name"),
											(String) session
													.getAttribute("project"),
											week, updateThisTR.getDate(),
											signed, active, array, matrix);
									if (uTR.getTotalTime() < 10081) {
										if (db.updateTR(uTR,
												updateThisTR.getWeek())) {
											error = "<p>Time report updated!";
										} else {
											error = "<p>Time report for that week already exists!";
										}
									} else {
										error = "<p>You can't work more than 10080 minutes in one week.";
									}
								} else {
									error = "<p>0 is not a valid week.";
								}
							} catch (NumberFormatException e) {
								error = "<p> One or more of the fields are not numbers!";
							}
						} else {
							error = "Time report is signed! Get Project leader to unsign it!";
						}
					}
					out.println(error);
				}

				if (state == NEWTR) {
					Date d = Calendar.getInstance().getTime();
					String date = d.getYear() + 1900 + "-" + (d.getMonth() + 1)
							% 12 + "-" + d.getDate();

					out.print(gen.submitTimeReportForm(
							(String) session.getAttribute("name"),
							(String) session.getAttribute("project"), date));

					if (request.getParameter("week") != null) {
						try {
							int week = Integer.parseInt(request
									.getParameter("week"));
							if (week != 0) {

								Boolean active = true;
								Boolean signed = false;
								int[] array = new int[9];
								int[][] matrix = new int[9][4];

								for (int k = 0; k < 9; k++) {
									array[k] = Integer.parseInt(request
											.getParameter(Integer
													.toString(k + 1)));
								}
								for (int i = 0; i < 9; i++) {
									for (int j = 0; j < 4; j++) {
										matrix[i][j] = Integer.parseInt(request
												.getParameter(Integer
														.toString(i)
														+ Integer.toString(j)));
									}
								}
								TimeReport tr = new TimeReport(
										(String) session.getAttribute("name"),
										(String) session
												.getAttribute("project"), week,
										date, signed, active, array, matrix);
								if (tr.getTotalTime() < 10081) {
									if (db.newTR(tr)) {
										error = "<p>Time report created!";
									} else {
										error = "<p>Time report for that week already exists!";
									}
								} else {
									error = "<p>You can't work more than 10080 minutes in one week.";
								}
							} else {
								error = "<p>0 is not a valid week.";
							}
						} catch (NumberFormatException e) {
							System.err.println(e.toString());
							error = "<p> One or more of the fields are not numbers!";
						}
					}
					out.println(error);
				}
				out.print(gen.getBot());
				out.close();
			}
		}
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
	}
}